import * as lsp from "vscode-languageserver/node";
import { OpenDialogOptions, QuickPickOptions } from "../common/types";
import { languageServerRequests } from "./types";

export interface WithProgressParam {
    readonly message: string;
    readonly reporter: lsp.WorkDoneProgressReporter;
}

export interface LanguageServiceClient {
    createProgressReporter(): Promise<lsp.WorkDoneProgressReporter>;
    withProgress<R>(param: WithProgressParam, task: (reporter: lsp.WorkDoneProgressReporter) => Promise<R>): Promise<R>;
    publishDiagnostics(param: lsp.PublishDiagnosticsParams): void;
    sendNotification<P>(type: lsp.NotificationType<P>, params: P): Promise<void>;
    sendRequest<P, R>(type: lsp.RequestType<P, R, void>, param: P): Promise<R>;
    showErrorMessage(message: string): void;
    logMessage(param: lsp.LogMessageParams): void;
    showInformationMessage(title: string, ...args: lsp.MessageActionItem[]): Promise<lsp.MessageActionItem | undefined>;
    showQuickPick(param: QuickPickOptions): Promise<string | undefined>;
    showOpenFileDialog(param: OpenDialogOptions): Promise<string[] | undefined>;
}

export function createLanguageServiceClient(connection: lsp.Connection): LanguageServiceClient {

    return {
        publishDiagnostics(param) {
            connection.sendDiagnostics(param);
        },
        async sendNotification(type, params) {
            await connection.sendNotification(type, params);
        },
        async sendRequest(type, param) {
            return await connection.sendRequest(type, param);
        },
        async createProgressReporter() {
            return await connection.window.createWorkDoneProgress();
        },
        async withProgress(param, task) {
            param.reporter.begin(param.message);
            return task(param.reporter).then(result => {
                param.reporter.done();
                return result;
            });
        },
        showErrorMessage(message) {
            connection.sendNotification(lsp.ShowMessageNotification.type, { type: lsp.MessageType.Error, message });
        },
        logMessage(param) {
            connection.sendNotification(lsp.LogMessageNotification.type, param);
        },
        async showInformationMessage(title, ...args) {
            return await connection.window.showInformationMessage(title, ...args);
        },
        async showQuickPick(param) {
            return await connection.sendRequest(languageServerRequests["dsclient/showQuickPickFile"], param);
        },
        async showOpenFileDialog(param) {
            return await connection.sendRequest(languageServerRequests["dsclient/showOpenFileDialog"], param);
        },
    };


}


